﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Management;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;
using Microsoft.Win32; 

namespace QZoneMessage
{
    public class regedit
    {
        public static long VisitCount = 0;
        public static bool REGISTERED = false;
        public static string MachCode = "";
        public static string AuthCode = "";

        #region 注册判断
        public static bool Judge_Whether_Registered()
        {
            bool IsRegister = false;
            MachCode = Get_Harddisk_Serial();
            ///采用哪种算法
            AuthCode = DCB002(MachCode);
            ///
            if ((Read_Registration_Code() == AuthCode) && (AuthCode != ""))
            {
                IsRegister = true;
            }
            return IsRegister;
        }
        public static string Get_Harddisk_Serial()
        {
            string HDid = "";
            ManagementClass cimobject = new ManagementClass("Win32_DiskDrive");
            ManagementObjectCollection moc = cimobject.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                HDid = (string)mo.Properties["Model"].Value;
                return HDid;
            }
            return "获取机器码出错!";
        }
        #endregion

        #region 读写注册表
        public static string Read_Registration_Code()
        {
            string RegInfo = "";
            try
            {
                RegistryKey myreg = Registry.LocalMachine.OpenSubKey("software\\Doucube");
                RegInfo = myreg.GetValue("QZoneMessager").ToString();
                myreg.Close();
            }
            catch (Exception)
            {
                RegInfo = "";
                //throw;
            }
            return RegInfo;
        }
        public static string Write_Registration_Code(string value)
        {
            RegistryKey LocalMachineKey = Registry.LocalMachine;
            RegistryKey CreateDcbKey = LocalMachineKey.CreateSubKey("software\\Doucube");
            RegistryKey WriteDcbKey = LocalMachineKey.OpenSubKey("software\\Doucube", true); //该项必须已存在
            WriteDcbKey.SetValue("QZoneMessager", value, RegistryValueKind.String);
            LocalMachineKey.Close();
            return string.Empty;
        }
        #endregion

        #region 加密算法列表
        #region 算法1 未证实的SHA1 & MD5
        /// <summary>  
        /// SHA1加密字符串  
        /// </summary>  
        /// <param name="source">源字符串</param>  
        /// <returns>加密后的字符串</returns>  
        public static string SHA1(string source)
        {
            return (source != "") ? (FormsAuthentication.HashPasswordForStoringInConfigFile(source, "SHA1")) : "";
        }
        /// <summary>  
        /// MD5加密字符串  
        /// </summary>  
        /// <param name="source">源字符串</param>  
        /// <returns>加密后的字符串</returns>  
        public static string MD5(string source)
        {
            return (source != "") ? (FormsAuthentication.HashPasswordForStoringInConfigFile(source, "MD5")) : "";
        }
        #endregion

        #region 算法2 可逆加密解密 DES?
        string KEY_64 = "jzw7tz8g";//注意了，是8个字符，64位    
        string IV_64 = "tvbzn9i7";//注意了，是8个字符，64位
        /// <summary>
        /// 加密的方法，通过2个密匙进行加密
        /// </summary>
        /// <param name="data">通过Md5加密一次</param>
        /// <param name="KEY_64"></param>
        /// <param name="IV_64"></param>
        /// <returns></returns>
        private string Encode(string data, string KEY_64, string IV_64)
        {
            byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
            byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);

            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
            int i = cryptoProvider.KeySize;
            MemoryStream ms = new MemoryStream();
            CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);

            StreamWriter sw = new StreamWriter(cst);
            sw.Write(data);
            sw.Flush();
            cst.FlushFinalBlock();
            sw.Flush();
            return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);

        }
        /// <summary>
        /// 解密的方法（）
        /// </summary>
        /// <param name="data"></param>
        /// <param name="KEY_64"></param>
        /// <param name="IV_64"></param>
        /// <returns></returns>
        private string Decode(string data, string KEY_64, string IV_64)
        {
            byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
            byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);

            byte[] byEnc;
            try
            {
                byEnc = Convert.FromBase64String(data);
            }
            catch
            {
                return null;
            }

            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
            MemoryStream ms = new MemoryStream(byEnc);
            CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
            StreamReader sr = new StreamReader(cst);
            return sr.ReadToEnd();
        }
        #endregion

        #region 算法3 MD5不可逆加密  
        //32位加密  
        public string GetMD5_32(string s, string _input_charset)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] t = md5.ComputeHash(Encoding.GetEncoding(_input_charset).GetBytes(s));
            StringBuilder sb = new StringBuilder(32);
            for (int i = 0; i < t.Length; i++)
            {
                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
            }
            return sb.ToString();
        }
        //16位加密  
        public static string GetMd5_16(string ConvertString)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
            t2 = t2.Replace("-", "");
            return t2;
        }
        #endregion

        #region 算法4 对称加密
        private SymmetricAlgorithm mobjCryptoService;  
        private string Key;  
        /// <summary>     
        /// 对称加密类的构造函数     
        /// </summary>     
        public void SymmetricMethod()  
        {  
            mobjCryptoService = new RijndaelManaged();  
            Key = "Guz(%&hj7x89H$yuBI0456FtmaT5&fvHUFCy76*h%(HilJ$lhj!y6&(*jkP87jH7";  
        }  
        /// <summary>     
        /// 获得密钥     
        /// </summary>     
        /// <returns>密钥</returns>     
        private byte[] GetLegalKey()  
        {  
            string sTemp = Key;  
            mobjCryptoService.GenerateKey();  
            byte[] bytTemp = mobjCryptoService.Key;  
            int KeyLength = bytTemp.Length;  
            if (sTemp.Length > KeyLength)  
                sTemp = sTemp.Substring(0, KeyLength);  
            else if (sTemp.Length < KeyLength)  
                sTemp = sTemp.PadRight(KeyLength, ' ');  
            return ASCIIEncoding.ASCII.GetBytes(sTemp);  
        }  
        /// <summary>     
        /// 获得初始向量IV     
        /// </summary>     
        /// <returns>初试向量IV</returns>     
        private byte[] GetLegalIV()  
        {  
            string sTemp = "E4ghj*Ghg7!rNIfb&95GUY86GfghUb#er57HBh(u%g6HJ($jhWk7&!hg4ui%$hjk";  
            mobjCryptoService.GenerateIV();  
            byte[] bytTemp = mobjCryptoService.IV;  
            int IVLength = bytTemp.Length;  
            if (sTemp.Length > IVLength)  
                sTemp = sTemp.Substring(0, IVLength);  
            else if (sTemp.Length < IVLength)  
                sTemp = sTemp.PadRight(IVLength, ' ');  
            return ASCIIEncoding.ASCII.GetBytes(sTemp);  
        }  
        /// <summary>     
        /// 加密方法     
        /// </summary>     
        /// <param name="Source">待加密的串</param>     
        /// <returns>经过加密的串</returns>     
        public string Encrypto(string Source)  
        {  
            byte[] bytIn = UTF8Encoding.UTF8.GetBytes(Source);  
            MemoryStream ms = new MemoryStream();  
            mobjCryptoService.Key = GetLegalKey();  
            mobjCryptoService.IV = GetLegalIV();  
            ICryptoTransform encrypto = mobjCryptoService.CreateEncryptor();  
            CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);  
            cs.Write(bytIn, 0, bytIn.Length);  
            cs.FlushFinalBlock();  
            ms.Close();  
            byte[] bytOut = ms.ToArray();  
            return Convert.ToBase64String(bytOut);  
        }  
        /// <summary>     
        /// 解密方法     
        /// </summary>     
        /// <param name="Source">待解密的串</param>     
        /// <returns>经过解密的串</returns>     
        public string Decrypto(string Source)  
        {  
            byte[] bytIn = Convert.FromBase64String(Source);  
            MemoryStream ms = new MemoryStream(bytIn, 0, bytIn.Length);  
            mobjCryptoService.Key = GetLegalKey();  
            mobjCryptoService.IV = GetLegalIV();  
            ICryptoTransform encrypto = mobjCryptoService.CreateDecryptor();  
            CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);  
            StreamReader sr = new StreamReader(cs);  
            return sr.ReadToEnd();  
        } 
        #endregion

        #region 算法5 DES
        //默认密钥向量  
        private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
        /// <summary>  
        /// DES加密字符串  
        /// </summary>  
        /// <param name="encryptString">待加密的字符串</param>  
        /// <param name="encryptKey">加密密钥,要求为8位</param>  
        /// <returns>加密成功返回加密后的字符串，失败返回源串</returns>  
        public static string EncryptDES(string encryptString, string encryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIV = Keys;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }
        /// <summary>  
        /// DES解密字符串  
        /// </summary>  
        /// <param name="decryptString">待解密的字符串</param>  
        /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>  
        /// <returns>解密成功返回解密后的字符串，失败返源串</returns>  
        public static string DecryptDES(string decryptString, string decryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
                byte[] rgbIV = Keys;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }
        } 

        #endregion

        #region 算法6 RC2
        /// <summary>
        /// RC2 加密(用变长密钥对大量数据进行加密)
        /// </summary>
        /// <param name="EncryptString">待加密密文</param>
        /// <param name="EncryptKey">加密密钥</param>
        /// <returns>returns</returns>
        public static string RC2Encrypt(string EncryptString, string EncryptKey)
        {
            if (string.IsNullOrEmpty(EncryptString)) { throw (new Exception("密文不得为空")); }
            if (string.IsNullOrEmpty(EncryptKey)) { throw (new Exception("密钥不得为空")); }
            if (EncryptKey.Length < 5 || EncryptKey.Length > 16) { throw (new Exception("密钥必须为5-16位")); }
            string m_strEncrypt = "";
            byte[] m_btIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            RC2CryptoServiceProvider m_RC2Provider = new RC2CryptoServiceProvider();
            try
            {
                byte[] m_btEncryptString = Encoding.Default.GetBytes(EncryptString);
                MemoryStream m_stream = new MemoryStream();
                CryptoStream m_cstream = new CryptoStream(m_stream, m_RC2Provider.CreateEncryptor(Encoding.Default.GetBytes(EncryptKey), m_btIV), CryptoStreamMode.Write);
                m_cstream.Write(m_btEncryptString, 0, m_btEncryptString.Length);
                m_cstream.FlushFinalBlock();
                m_strEncrypt = Convert.ToBase64String(m_stream.ToArray());
                m_stream.Close(); m_stream.Dispose();
                m_cstream.Close(); m_cstream.Dispose();
            }
            catch (IOException ex) { throw ex; }
            catch (CryptographicException ex) { throw ex; }
            catch (ArgumentException ex) { throw ex; }
            catch (Exception ex) { throw ex; }
            finally { m_RC2Provider.Clear(); }
            return m_strEncrypt;
        }
        /// <summary>
        /// RC2 解密(用变长密钥对大量数据进行加密)
        /// </summary>
        /// <param name="DecryptString">待解密密文</param>
        /// <param name="DecryptKey">解密密钥</param>
        /// <returns>returns</returns>
        public static string RC2Decrypt(string DecryptString, string DecryptKey)
        {
            if (string.IsNullOrEmpty(DecryptString)) { throw (new Exception("密文不得为空")); }
            if (string.IsNullOrEmpty(DecryptKey)) { throw (new Exception("密钥不得为空")); }
            if (DecryptKey.Length < 5 || DecryptKey.Length > 16) { throw (new Exception("密钥必须为5-16位")); }
            byte[] m_btIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            string m_strDecrypt = "";
            RC2CryptoServiceProvider m_RC2Provider = new RC2CryptoServiceProvider();
            try
            {
                byte[] m_btDecryptString = Convert.FromBase64String(DecryptString);
                MemoryStream m_stream = new MemoryStream();
                CryptoStream m_cstream = new CryptoStream(m_stream, m_RC2Provider.CreateDecryptor(Encoding.Default.GetBytes(DecryptKey), m_btIV), CryptoStreamMode.Write);
                m_cstream.Write(m_btDecryptString, 0, m_btDecryptString.Length);
                m_cstream.FlushFinalBlock();
                m_strDecrypt = Encoding.Default.GetString(m_stream.ToArray());
                m_stream.Close(); m_stream.Dispose();
                m_cstream.Close(); m_cstream.Dispose();
            }
            catch (IOException ex) { throw ex; }
            catch (CryptographicException ex) { throw ex; }
            catch (ArgumentException ex) { throw ex; }
            catch (Exception ex) { throw ex; }
            finally { m_RC2Provider.Clear(); }
            return m_strDecrypt;
        }
        #endregion

        #region 算法7 3DES
        /// <summary>
        /// 3DES 加密(基于DES，对一块数据用三个不同的密钥进行三次加密，强度更高)
        /// </summary>
        /// <param name="EncryptString">待加密密文</param>
        /// <param name="EncryptKey1">密钥一</param>
        /// <param name="EncryptKey2">密钥二</param>
        /// <param name="EncryptKey3">密钥三</param>
        /// <returns>returns</returns>
        public static string DES3Encrypt(string EncryptString, string EncryptKey1, string EncryptKey2, string EncryptKey3)
        {
            string m_strEncrypt = "";
            try
            {
                m_strEncrypt = DecryptDES(EncryptString, EncryptKey3);
                m_strEncrypt = DecryptDES(m_strEncrypt, EncryptKey2);
                m_strEncrypt = DecryptDES(m_strEncrypt, EncryptKey1);
            }
            catch (Exception ex) { throw ex; }
            return m_strEncrypt;
        }
        /// <summary>
        /// 3DES 解密(基于DES，对一块数据用三个不同的密钥进行三次加密，强度更高)
        /// </summary>
        /// <param name="DecryptString">待解密密文</param>
        /// <param name="DecryptKey1">密钥一</param>
        /// <param name="DecryptKey2">密钥二</param>
        /// <param name="DecryptKey3">密钥三</param>
        /// <returns>returns</returns>
        public static string DES3Decrypt(string DecryptString, string DecryptKey1, string DecryptKey2, string DecryptKey3)
        {
            string m_strDecrypt = "";
            try
            {
                m_strDecrypt = EncryptDES(DecryptString, DecryptKey1);
                m_strDecrypt = EncryptDES(m_strDecrypt, DecryptKey2);
                m_strDecrypt = EncryptDES(m_strDecrypt, DecryptKey3);
            }
            catch (Exception ex) { throw ex; }
            return m_strDecrypt;
        }
        #endregion

        #region 算法8 AES
        /// <summary>
        /// AES 加密(高级加密标准，是下一代的加密算法标准，速度快，安全级别高，目前 AES 标准的一个实现是 Rijndael 算法)
        /// </summary>
        /// <param name="EncryptString">待加密密文</param>
        /// <param name="EncryptKey">加密密钥</param>
        /// <returns></returns>
        public static string AESEncrypt(string EncryptString, string EncryptKey)
        {
            if (string.IsNullOrEmpty(EncryptString)) { throw (new Exception("密文不得为空")); }
            if (string.IsNullOrEmpty(EncryptKey)) { throw (new Exception("密钥不得为空")); }
            string m_strEncrypt = "";
            byte[] m_btIV = Convert.FromBase64String("Rkb4jvUy/ye7Cd7k89QQgQ==");
            Rijndael m_AESProvider = Rijndael.Create();
            try
            {
                byte[] m_btEncryptString = Encoding.Default.GetBytes(EncryptString);
                MemoryStream m_stream = new MemoryStream();
                CryptoStream m_csstream = new CryptoStream(m_stream, m_AESProvider.CreateEncryptor(Encoding.Default.GetBytes(EncryptKey), m_btIV), CryptoStreamMode.Write);
                m_csstream.Write(m_btEncryptString, 0, m_btEncryptString.Length);
                m_csstream.FlushFinalBlock();
                m_strEncrypt = Convert.ToBase64String(m_stream.ToArray());
                m_stream.Close(); m_stream.Dispose();
                m_csstream.Close(); m_csstream.Dispose();
            }
            catch (IOException ex) { throw ex; }
            catch (CryptographicException ex) { throw ex; }
            catch (ArgumentException ex) { throw ex; }
            catch (Exception ex) { throw ex; }
            finally { m_AESProvider.Clear(); }
            return m_strEncrypt;
        }
        /// <summary>
        /// AES 解密(高级加密标准，是下一代的加密算法标准，速度快，安全级别高，目前 AES 标准的一个实现是 Rijndael 算法)
        /// </summary>
        /// <param name="DecryptString">待解密密文</param>
        /// <param name="DecryptKey">解密密钥</param>
        /// <returns></returns>
        public static string AESDecrypt(string DecryptString, string DecryptKey)
        {
            if (string.IsNullOrEmpty(DecryptString)) { throw (new Exception("密文不得为空")); }
            if (string.IsNullOrEmpty(DecryptKey)) { throw (new Exception("密钥不得为空")); }
            string m_strDecrypt = "";
            byte[] m_btIV = Convert.FromBase64String("Rkb4jvUy/ye7Cd7k89QQgQ==");
            Rijndael m_AESProvider = Rijndael.Create();
            try
            {
                byte[] m_btDecryptString = Convert.FromBase64String(DecryptString);
                MemoryStream m_stream = new MemoryStream();
                CryptoStream m_csstream = new CryptoStream(m_stream, m_AESProvider.CreateDecryptor(Encoding.Default.GetBytes(DecryptKey), m_btIV), CryptoStreamMode.Write);
                m_csstream.Write(m_btDecryptString, 0, m_btDecryptString.Length);
                m_csstream.FlushFinalBlock();
                m_strDecrypt = Encoding.Default.GetString(m_stream.ToArray());
                m_stream.Close(); m_stream.Dispose();
                m_csstream.Close(); m_csstream.Dispose();
            }
            catch (IOException ex) { throw ex; }
            catch (CryptographicException ex) { throw ex; }
            catch (ArgumentException ex) { throw ex; }
            catch (Exception ex) { throw ex; }
            finally { m_AESProvider.Clear(); }
            return m_strDecrypt;
        }
        #endregion

        #region 算法9
        #endregion

        #region 算法10
        #endregion

        #endregion

        //当前应用使用的算法，基于上面的二次开发
        public static string DCB002(string source)
        {
            string encrypt_result = string.Empty;

            string encrypt_sha1 = SHA1(source);
            string encrypt_md5 = MD5(source);
            string encrypt_all_1 = encrypt_sha1 + encrypt_md5;
            string encrypt_all_2 = encrypt_md5 + encrypt_sha1;

            List<string> mList_1 = new List<string>();
            int start_1 = 2;
            int gap_1 = 3;
            for (int i = start_1; i < encrypt_all_1.Length; i += gap_1)
            {
                string x = "";
                x = encrypt_all_1.Substring(i, 1);
                if (i == start_1 + 3 * gap_1)
                {
                    mList_1.Add("9");
                }
                else if (i == start_1 + 6 * gap_1)
                {
                    mList_1.Add("3");
                }
                else
                {
                    mList_1.Add(x);
                }
                if (mList_1.Count >= 10)
                {
                    break;
                }
            }

            List<string> mList_2 = new List<string>();
            int start_2 = 7;
            int gap_2 = 5;

            for (int j = start_2; j < encrypt_all_2.Length; j += gap_2)
            {
                string x = "";
                x = encrypt_all_2.Substring(j, 1);
                if (j == start_2 + 2 * gap_2)
                {
                    mList_2.Add("C");
                }
                else if (j == start_2 + 4 * gap_2)
                {
                    mList_2.Add("0");
                }
                else
                {
                    mList_2.Add(x);
                }
                
                if (mList_2.Count >= 6)
                {
                    break;
                }
            }

            encrypt_result = string.Join("", mList_1.ToArray()) + string.Join("", mList_2.ToArray());

            return encrypt_result;
        }

    }
}
